OpenFisca Editor検証: Gemini Pro1.5
まとめ
URL指定よりもhtml挿入の方が細かい要件を拾ってくれる
Geminiと比較しGemini Pro 1.5は実際の処理に近い内容が出力された
「OpenFiscaらしいソースコード」よりもリファクタリング前の一般的なソースコードの方が学習精度が高かった
一般的なPython学習データ→一般的な生成コード→OpenFisca的なコード という変換を行う?
開発スピードについて
現状は人手の方が速い
レビューで修正するためにはプログラミングと制度両方の知識が必要
分業した場合は既存より速くなる可能性はある
コード生成者がたたき台を作成→別の開発者がそれをもとに開発
検証1 ColablatoryによるHTML埋め込み
以下のプロンプトを使用しコード生成
code:md
制度情報をもとにソースコードを生成してください。
制度情報: 「児童育成手当」
`
{page_content(url_sample)}
`
ソースコード:
`
class 児童育成手当(Variable):
value_type = float
entity = 世帯
definition_period = DAY
label = "保護者への児童手当"
documentation = """
渋谷区の児童育成手当制度
- 〒150-8010 東京都渋谷区宇田川町1-1
- 渋谷区子ども青少年課子育て給付係
- 03-3463-2558
"""
def formula(対象世帯, 対象期間, parameters):
居住都道府県 = 対象世帯("居住都道府県", 対象期間)
# 東京都以外は対象外
if 居住都道府県 != "東京都":
return 0
児童育成手当 = parameters(対象期間).福祉.育児.児童育成手当
世帯高所得 = 対象世帯("特別児童扶養手当の控除後世帯高所得", 対象期間)
扶養人数 = 対象世帯("扶養人数", 対象期間)0 所得制限限度額 = 児童育成手当.所得制限限度額扶養人数 所得条件 = 世帯高所得 < 所得制限限度額
ひとり親世帯である = 対象世帯("ひとり親", 対象期間)
学年 = 対象世帯.members("学年", 対象期間)
上限学年以下の人数 = 対象世帯.sum(学年 <= 児童育成手当.上限学年)
手当条件 = ひとり親世帯である * 所得条件
return 手当条件 * 上限学年以下の人数 * 児童育成手当.金額
`
制度情報 「受験生チャレンジ支援貸付」
`
{page_content(url)}
`
ソースコード:
結果:WebサイトのHTML取得で403エラーが発生し内容を取得できなかった
ローカルからcurl でリクエストした場合は成功したため、Colablatoryからwebサイトへのアクセスが禁止されている?
code:html
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ...省略 -->
<title>
お探しのページを表示できません
</title>
</head>
<body>
<div class="message-container">
<p class="br-t"></p>
<h2>
お探しのページを表示できません
</h2>
<p>
申し訳ございません。お客様がお探しのページにアクセスできませんでした。<br>
入力したURLや値が正しくない可能性がございます。<br>
TOPページから再度アクセスして頂けますよう、お願い申し上げます。
</p>
<p class="br-t"></p>
</div>
</body>
</html>
検証内容
Gemini Pro 1.5で以下のプロンプトを使用しコード生成
Colablatoryも使用したがレスポンスが403になってしまい取得できなかった
検証2 Gemini Pro 1.5を使用
使用プロンプトは同じ
制度説明webサイトのHTMLは手動で貼り付け
生成結果
code:python
class 受験生チャレンジ支援貸付(Variable):
value_type = float
entity = 世帯
definition_period = MONTH
label = "受験費用貸付"
documentation = """
東京都の受験生チャレンジ支援貸付事業
- 〒163-8001 東京都新宿区西新宿2丁目8番1号
- 東京都福祉局生活福祉部 地域福祉課 生活援助担当
- 03-5320-4072
"""
def formula(対象世帯, 対象期間, parameters):
居住都道府県 = 対象世帯("居住都道府県", 対象期間)
# 東京都以外は対象外
if 居住都道府県 != "東京都":
return 0
受験生チャレンジ支援貸付事業 = parameters(対象期間).福祉.育児.受験生チャレンジ支援貸付事業
世帯高所得 = 対象世帯("特別児童扶養手当の控除後世帯高所得", 対象期間)
扶養人数 = 対象世帯("扶養人数", 対象期間)0 所得制限限度額 = 受験生チャレンジ支援貸付事業.所得制限限度額扶養人数 所得条件 = 世帯高所得 < 所得制限限度額
ひとり親世帯である = 対象世帯("ひとり親", 対象期間)
学年 = 対象世帯.members("学年", 対象期間)
対象学年の人数 = 対象世帯.sum(学年.isin(受験生チャレンジ支援貸付事業.対象学年))
手当条件 = ひとり親世帯である * 所得条件
return 手当条件 * 対象学年の人数 * 受験生チャレンジ支援貸付事業.金額
足りない処理があるが概要はつかめている
検証3 コードの修正
上記回答に続けて「レビュー」のプロンプトを指示しコード修正
指示通りにコードが修正された
名前が児童育成手当になってしまったのはやむなし
code:md
下記のレビューを元にソースコードを修正してください。
- ひとり親世帯でない場合も手当条件を満たします。ひとり親世帯の場合は所得制限のみ修正してください。
- 手当条件に 預貯金 を追加する必要があります。
code:py
class 児童育成手当(Variable):
value_type = float
entity = 世帯
definition_period = DAY
label = "保護者への児童手当"
documentation = """
渋谷区の児童育成手当制度
- 〒150-8010 東京都渋谷区宇田川町1-1
- 渋谷区子ども青少年課子育て給付係
- 03-3463-2558
"""
def formula(対象世帯, 対象期間, parameters):
居住都道府県 = 対象世帯("居住都道府県", 対象期間)
# 東京都以外は対象外
if 居住都道府県 != "東京都":
return 0
児童育成手当 = parameters(対象期間).福祉.育児.児童育成手当
世帯高所得 = 対象世帯("特別児童扶養手当の控除後世帯高所得", 対象期間)
扶養人数 = 対象世帯("扶養人数", 対象期間)0 # ひとり親世帯の所得制限
if 対象世帯("ひとり親", 対象期間):
所得制限限度額 = 児童育成手当.ひとり親所得制限限度額扶養人数 else:
所得制限限度額 = 児童育成手当.所得制限限度額扶養人数 所得条件 = 世帯高所得 < 所得制限限度額
預貯金条件 = 対象世帯("預貯金", 対象期間) < 児童育成手当.預貯金限度額
学年 = 対象世帯.members("学年", 対象期間)
上限学年以下の人数 = 対象世帯.sum(学年 <= 児童育成手当.上限学年)
手当条件 = 所得条件 * 預貯金条件
return 手当条件 * 上限学年以下の人数 * 児童育成手当.金額
検証4 プロンプトで与えるコードをOpenFisca的な書き方(現在のdevelopブランチ)に修正
if文がない
要素参照の代わりにnp.selectを使用
それ以外は上記と同様
精度が下がり、one-shotで与えた実装との乖離も大きくなってしまった
code:python
class 受験生チャレンジ支援貸付事業(Loan):
"""
東京都の受験生チャレンジ支援貸付事業
詳細は以下を参照。
"""
interest_rate = 0 # 無利子
grace_period = 0 # 据置期間なし
entity = 世帯
definition_period = YEAR
def __init__(self):
# 貸付資金の種類
self.funds = {
"学習塾等受講料": {
"limit": 200_000, # 上限20万円
"target_grade": 9, 12, # 中学3年生・高校3年生又はこれに準じる方 # 対象となる学習塾等の費用(一定期間以上継続して生徒・学生に対し有償での学力の教授を直接または通信で行うもの)
},
"受験料(中学3年生)": {
"limit": 27_400, # 上限2万7400円
"target_grade": 9, # 中学3年生又はこれに準じる方 # 対象となる高等学校等の受験料(学校教育法に規定する高等学校、特別支援学校(高等部)、高等専門学校)
},
"受験料(高校3年生)": {
"limit": 80_000, # 上限8万円
"target_grade": 12, # 高校3年生又はこれに準じる方 # 対象となる大学等の受験料(学校教育法に規定する大学、短期大学、専門職大学、専修学校、各種学校)
},
}
def is_eligible(self, 対象世帯, 対象期間, parameters):
"""
貸付 eligibility を判定する。
Args:
対象世帯 (Household): 判定対象の世帯
対象期間 (Period): 判定対象の期間
parameters (Parameters): パラメータ
Returns:
bool: 貸付 eligibility を満たす場合は True、そうでない場合は False
"""
# 居住地条件
居住都道府県 = 対象世帯("居住都道府県", 対象期間)
居住地条件 = 居住都道府県 == "東京都"
# 世帯人数
世帯人数 = 対象世帯("世帯人数", 対象期間)
# 世帯収入条件
総収入 = 対象世帯("総収入", 対象期間)
合計所得金額 = 対象世帯("合計所得金額", 対象期間)
収入基準額 = parameters(対象期間).福祉.育児.受験生チャレンジ支援貸付事業.収入基準額
# NOTE: 直接 収入基準額[世帯人数] のように要素参照すると型が合わず複数世帯の場合に計算できないためnp.selectを使用
総収入条件 = np.select(
[総収入 < 収入基準額.総収入i for i in range(2, 7)], False,
)
合計所得金額条件 = np.select(
[合計所得金額 < 収入基準額.合計所得金額i for i in range(2, 7)], False,
)
# ひとり親世帯
ひとり親世帯である = 対象世帯("ひとり親", 対象期間)
# その他の条件
資産条件 = (
対象世帯("預貯金等資産の保有額", 対象期間) < 6_000_000
) # 預貯金等資産の保有額が600万円以下
不動産条件 = not 対象世帯(
"土地・建物の所有", 対象期間
) # 土地・建物を所有していない(現在住んでいる場所は除く)
生活保護条件 = not 対象世帯(
"生活保護", 対象期間
) # 生活保護受給世帯の世帯主または構成員でない
債務条件 = not 対象世帯(
"債務の滞納", 対象期間
) # 世帯員に債務の滞納がない(他の公的資金、税金等を含む)
# 生計中心者条件
生計中心者 = 対象世帯("生計中心者", 対象期間)
return (
居住地条件
and (総収入条件 | 合計所得金額条件)
and 資産条件
and 不動産条件
and 生活保護条件
and 債務条件
and 生計中心者
)
def calc_loan_amount(self, 対象世帯, 対象期間, parameters):
"""
貸付金額を計算する。
Args:
対象世帯 (Household): 貸付を受ける世帯
対象期間 (Period): 貸付を受ける期間
parameters (Parameters): パラメータ
Returns:
float: 貸付金額
"""
if not self.is_eligible(対象世帯, 対象期間, parameters):
return 0
学年 = 対象世帯.members("学年", 対象期間)0 is_single_parent = 対象世帯("ひとり親", 対象期間)
世帯人数 = 対象世帯("世帯人数", 対象期間)
return 0
available_funds = [
fund_name
for fund_name, fund in self.funds.items()
]
# ひとり親世帯への上乗せ
if is_single_parent:
# 収入基準額
収入基準額 = parameters(対象期間).福祉.育児.受験生チャレンジ支援貸付事業.収入基準額
loan_amount = 0
for fund_name in available_funds:
# 収入基準額による制限
if "ひとり親世帯" in fund_name:
limit = min(limit, 収入基準額.ひとり親世帯世帯人数 - 対象世帯("総収入", 対象期間)) else:
limit = min(limit, 収入基準額.一般世帯世帯人数 - 対象世帯("総収入", 対象期間)) loan_amount = min(limit, loan_amount + limit)
return loan_amount